<template>
  <div v-if="item.commonAttr" :style="scaleComponentStyle"
    ref="injectTemplate" :class="getGroupClass" :id="item.id">
    <component v-for="(item_, i) in domComponents" :key="item_.id + '_' + i"
      :style="getConstyles(item_)" :is="item_.type"
      :item="item_" :pageId="pageId" :popId="popId"></component>
  </div>
  <div v-else :style="scaleStyle" class="page-con">
    <component v-for="(item_, i) in domComponents" :key="item_.id + '_' + i"
      :style="getConstyles(item_)" :is="item_.type"
      :item="item_" :pageId="pageId" :popId="popId"></component>
  </div>
</template>

<script>
import { mapState } from 'vuex'
import { PAGE_TYPE } from '@/common/const'
import { MOBILE_WID_HEI, H5_TYPE } from '@/common/const-dif'
import { getPxOVwByValue } from '@/store/utils'
import { template } from '@/components/utils/template'
import { commonUtils } from '@/components/utils/common-utils'
import { DOM_CID, CREATEJS_CID, PHASER_CID } from '@/common/const-wb'
import { INJECT_GROUP_CLASS_NAME } from '@/common/const-inject-class'
import { SCROLL_TRIGGER_TYPE_MAP } from '@/common/const-animates'
import { defineAsyncComponent, reactive } from 'vue'
import { isHasOwnProperty } from '@/plugins/utils'
import { ANIMATE_TRIGGER_TYPE_MAP } from '@/common/const-animates'

const components = {
  GroupCarousel: defineAsyncComponent(() => import('@/components/lists/group-carousel.vue')),
  GroupComponent: defineAsyncComponent(() => import('@/components/group-component.vue')),

  WbText: defineAsyncComponent(() => import('@/components/common/wb-text.vue')),
  WbImg: defineAsyncComponent(() => import('@/components/common/wb-img.vue')),
  WbIcon: defineAsyncComponent(() => import('@/components/common/wb-icon.vue')),
  WbSvgIcon: defineAsyncComponent(() => import('@/components/common/wb-svg-icon.vue')),
  WbImgs: defineAsyncComponent(() => import('@/components/common/wb-imgs.vue')),
  WbAudio: defineAsyncComponent(() => import('@/components/common/wb-audio.vue')),
  WbVideo: defineAsyncComponent(() => import('@/components/common/wb-video.vue')),
  WbVideos: defineAsyncComponent(() => import('@/components/common/wb-videos.vue')),
  WbTimer: defineAsyncComponent(() => import('@/components/common/wb-timer.vue')),
  WbMenu: defineAsyncComponent(() => import('@/components/common/wb-menu.vue')),
  WbCamera: defineAsyncComponent(() => import('@/components/common/wb-camera.vue')),
  WbTurnBook: defineAsyncComponent(() => import('@/components/common/wb-turn-book.vue')),
  WbScrollContainer: defineAsyncComponent(() => import('@/components/common/wb-scroll-container.vue')),
  WbMoveable: defineAsyncComponent(() => import('@/components/common/wb-moveable.vue')),
  WbCalendar: defineAsyncComponent(() => import('@/components/common/wb-calendar.vue')),
  WbGraspDoll: defineAsyncComponent(() => import('@/components/common/wb-grasp-doll.vue')),
  WbBg: defineAsyncComponent(() => import('@/components/common/wb-bg.vue')),
  WbProcess: defineAsyncComponent(() => import('@/components/common/wb-process.vue')),
  WbFlipMc: defineAsyncComponent(() => import('@/components/common/wb-flip-mc.vue')),
  WbSlotMachine: defineAsyncComponent(() => import('@/components/common/wb-slot-machine.vue')),
  WbNoticeBar: defineAsyncComponent(() => import('@/components/common/wb-notice-bar.vue')),

  WbCommonList: defineAsyncComponent(() => import('@/components/lists/wb-common-list.vue')),
  WbTable: defineAsyncComponent(() => import('@/components/lists/wb-table.vue')),
  WbCarousel: defineAsyncComponent(() => import('@/components/lists/wb-carousel.vue')),
  WbItemCommon: defineAsyncComponent(() => import('@/components/items/wb-item-common.vue')),
  WbHead: defineAsyncComponent(() => import('@/components/wb/wb-head.vue')),
  //global
  WbIsPostEvent: defineAsyncComponent(() => import('@/components/global/wb-is-post-event.vue')),

  WbForm: defineAsyncComponent(() => import('@/components/form/wb-form.vue')),
  WbFormScore: defineAsyncComponent(() => import('@/components/form/wb-form-score.vue')),
  WbAddress: defineAsyncComponent(() => import('@/components/form/wb-address.vue')),
  WbInput: defineAsyncComponent(() => import('@/components/form/wb-input.vue')),
  WbBtn: defineAsyncComponent(() => import('@/components/form/wb-btn.vue')),
  WbRadio: defineAsyncComponent(() => import('@/components/form/wb-radio.vue')),
  WbCheckbox: defineAsyncComponent(() => import('@/components/form/wb-checkbox.vue')),
  WbDropdown: defineAsyncComponent(() => import('@/components/form/wb-dropdown.vue')),
  WbUpload: defineAsyncComponent(() => import('@/components/form/wb-upload.vue')),
  WbSwitch: defineAsyncComponent(() => import('@/components/form/wb-switch.vue')),

  //canvas cretejs phaser three
  WbBitmapText: defineAsyncComponent(() => import('@/components/games/createjs/wb-bitmap-text.vue')),
  WbMc: defineAsyncComponent(() => import('@/components/games/createjs/wb-mc.vue')),
  //paper
  WbPaper: defineAsyncComponent(() => import('@/components/games/paper/wb-paper.vue')),
  //pixi
  WbPixis: defineAsyncComponent(() => import('@/components/games/pixi/wb-pixis.vue')),
  //three
  WbPanorama: defineAsyncComponent(() => import('@/components/games/threejs/wb-panorama.vue')),
  WbThrees: defineAsyncComponent(() => import('@/components/games/threejs/wb-threes.vue')),
  //phaser
  WbPhasers: defineAsyncComponent(() => import('@/components/games/phaser/wb-phasers.vue')),
}
export default {
  name: "GroupComponent",
  components,
  mixins: [commonUtils, template],
  props:['item', 'pageId', 'popId'],
  setup () {
    const state =  reactive({
      isScrollAnimateClass: false,
      isCssAnimateClass: false,
    })
    const state_ = {
      animateStyle: {},
    }
    _.merge(state, state_)
    return state
  },
  created () {
    if(!this.isH5Edit) {
      let item_ = this.item;
      if(item_ && item_.commonAttr && item_.commonAttr.injectJsClass){
        if(INJECT_GROUP_CLASS_NAME[item_.commonAttr.injectJsClass]){
          import(`./js/${item_.commonAttr.injectJsClass}.js`).then((module) => {
            this.injectJsClass = new module.default();
            this.injectJsClass.init(item_);
          })
        }
      }
      // 1778
      if(this.item && this.item.commonAttr && this.item.commonAttr.groupInjectClassName){
        this.injectDomInCompData();
      }
    }
  },
  computed: {
    ...mapState({
      siteAttrs: state => state.attrs,
      pages: state => state.pages,
      pageIndex: state => state.pageIndex,
    }),
    getGroupClass() {
      let classes = [];
      let animateClass = {
        'group-component-con': true,
        'wid-hei-inherit': this.item.components.length > 0 ? false : true,
        'scroll-animate': this.isScrollAnimateClass,
        isHiddenComp: !this.item.commonAttr.isVisible,
        // 这里设置的是-打组本身的属性
        'component-gsap': this.item.animate && this.item.animate.isGsap && this.item.animate.triggerType == ANIMATE_TRIGGER_TYPE_MAP.auto,
      }
      //打组中的组件 按照参数设置 这里设置的是-打组下的组件的属性
      if(this.item.commonAttr.groupAnimateClass){
        animateClass['group-gsap'] = true;
      }
      if(this.item.commonAttr && this.item.commonAttr.scrollTrigger && this.item.commonAttr.scrollTrigger.groupClassName){
        classes.push(this.item.commonAttr.scrollTrigger.groupClassName);
        //moveToCenter
        if(this.commonAttr.scrollTrigger.scrollTriggerClasses){
          classes = _.concat(classes, this.commonAttr.scrollTrigger.scrollTriggerClasses);
        }
      }
      classes.push(animateClass);
      if(this.item.commonAttr.isFullScreen && this.item.commonAttr.classNames){
        let classNames = this.item.commonAttr.classNames.split(',');
        classes = _.concat(classes, classNames)
      }
      if(this.commonAttr.isDisplayY) {
        classes.push('scrollbar');
        classes.push(this.commonAttr.scrollbarType);
      }
      return classes;
    },
    scaleStyle(){
      let styles = {}
      if(this.item.styles && isHasOwnProperty(this.item.styles, "opacity")){
        styles.opacity = this.item.styles.opacity
      }
      let conAttr = this.item.conAttr
      //是组件，不是页面
      if(!this.isH5Edit && conAttr && this.siteAttrs.pageType == PAGE_TYPE.single && conAttr.realTop > 0){
        let scale_ = this.getScale(conAttr)
        styles['transform-origin'] = 'center top'
        styles['transform'] = 'scale(' + scale_ + ')'
      }
      return styles
    },
    scaleComponentStyle(){
      let styles = this.scaleStyle
      let styles_ = this.animateStyle
      return _.merge(styles_, styles)
    },
    domComponents() {
      if(this.isH5Edit){
        return this.getComponentsByCid(DOM_CID, CREATEJS_CID);
      }else{
        if(this.siteAttrs.h5Type == H5_TYPE.canvas){
          return this.getComponentsByCid(DOM_CID, PHASER_CID);
        }else{
          return this.getComponents();
        }
      }
    },
  },
  mounted(){
    let commonAttr = this.item.commonAttr;
    if(this.$refs.injectTemplate && commonAttr.isScrollTriggerGsap && commonAttr.scrollTriggerType == SCROLL_TRIGGER_TYPE_MAP.multiBg){
      this.$refs.injectTemplate.setAttribute("data-speed", parseFloat(commonAttr.scrollTrigger.speed))
    }
    const div = this.$refs.injectTemplate
    if(!div) return
    if(commonAttr && commonAttr.isDisplayY) {
      div.style['overflow-y'] = 'auto'
      div.style['padding-right'] = getPxOVwByValue(8)
    }else{
      div.style['overflow-y'] = 'visible'
    }
  },
  methods: {
    loadImgPlayAnimate(){
      if(this.item.components && this.item.components.length > 0){
        this.loadImgNum = 0;
        this.loadedImgNum = 0;
        const compData = this.item;
        this.loadedImgs(compData, true);

        this.loadEventGroupCb = window.setInterval(() => {
          this.loadedImgs(compData, false);
          if(this.loadedImgNum >= this.loadImgNum){
            window.clearInterval(this.loadEventGroupCb);
            this.playAnimate();
          }
        }, this.siteInfo.reloadTime)
      }
    },
    getComponentsByCid(minCid, maxCid) {
      let components = [];
      _.forEach(this.item.components, component => {
        let cid = component.cid
        if (cid >= minCid && cid < maxCid || (maxCid == CREATEJS_CID && component.components && component.components.length > 0)) {
          components.push(component);
        }
      });
      return components;
    },
    getComponents(){
      let components = []
      _.forEach(this.item.components, (componentData) => {
        if(componentData && !componentData.commonAttr.isPageCanvas)(
          components.push(componentData)
        )
      })
      return components;
    },
    getConstyles(item_) {
      const styles = item_.conStyles
      const conAttr = item_.conAttr
      //是组件，不是页面
      if(!this.isH5Edit && conAttr && this.siteAttrs.pageType == PAGE_TYPE.single && (conAttr.realTop > 0 || conAttr.otherCompHeight > 0)){
        let clientHeight = MOBILE_WID_HEI.clientHeight
        let reallyHeight = clientHeight*MOBILE_WID_HEI.adaptiveScale
        if(MOBILE_WID_HEI.adaptiveScale <= 1 && !this.siteInfo.md.isMobile){
          reallyHeight = clientHeight
          let currentPage = this.statePopId > 0 ? this.pops[this.popId-1] : this.pages[this.pageId-1];
          if(reallyHeight < currentPage.attrs.height) {
            reallyHeight = currentPage.attrs.height
          }
        }
        let top = 0;
        if(conAttr.realTop > 0){
          const scale_ = this.getScale(conAttr)
          const bottom = MOBILE_WID_HEI.height - conAttr.initTop - conAttr.height
          const compHei = conAttr.height
          // if(this.siteInfo.md.isMobile){
            //设计稿是750
            //只缩小，不放大，因此需要加上绝对值 reallyHeight > compHei那么就是高度比较高，也需要在调整一下bottom的值
            if(conAttr.realTop == 1){
              top = 0
              //顶部，只是缩放
            }else{
              top = (reallyHeight - conAttr.realTop - bottom - compHei*scale_)/2 + conAttr.realTop;
            }
            conAttr.top = top;
            styles["top"] = getPxOVwByValue(top)
          // }else{
          //   styles["bottom"] = getPxOVwByValue(bottom)
          // }
        }
        if(conAttr.otherCompHeight > 0){
          let difHeight = parseInt(clientHeight*MOBILE_WID_HEI.adaptiveScale) - (conAttr.height + conAttr.otherCompHeight)
          //需要调整的组件在顶部，那么上部会被切掉，居中显示
          if(conAttr.initTop == 0){
            top = difHeight/2;
          }else{
            if(difHeight < 0){
              difHeight = 0
            }
            top = reallyHeight - difHeight/2 - conAttr.height;
          }
          conAttr.top = top;
          styles["top"] = getPxOVwByValue(top)
        }
      }
      return styles
    },
    getScale(conAttr) {
      let compHei = conAttr.height
      let bottom = MOBILE_WID_HEI.height - conAttr.initTop - conAttr.height
      let clientHeight = MOBILE_WID_HEI.clientHeight
      let reallyHeight = clientHeight*MOBILE_WID_HEI.adaptiveScale
      if(MOBILE_WID_HEI.adaptiveScale <= 1 && !this.siteInfo.md.isMobile){
        reallyHeight = clientHeight
        let currentPage = this.statePopId > 0 ? this.pops[this.popId-1] : this.pages[this.pageId-1];
        if(reallyHeight < currentPage.attrs.height) {
          reallyHeight = currentPage.attrs.height
        }
      }
      //计算组件的应该有的真实高度与实际高度的比例
      //let pageCompHei = MOBILE_WID_HEI.height - conAttr.realTop - bottom
      //在依赖移动设备的高度动态的计算组件的高度
      let pageCompHei = parseInt(reallyHeight) - (conAttr.realTop + bottom)
      if(conAttr.realTop == 1){
        pageCompHei = parseInt(reallyHeight)
      }
      let scale = 1
      if(compHei > pageCompHei){
        scale = pageCompHei/compHei
      }
      return scale
    }
  },
  beforeUnmount(){
    if(this.injectJsClass){
      this.injectJsClass.destroy();
      this.item.vueContainer = null;
    }
  }
};
</script>